package cn.com.helloworld;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipInputStream;

import org.activiti.bpmn.model.Activity;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.springframework.util.FileCopyUtils;

public class HelloWorld {
	//获取流程引擎对象
	//getDefaultProcessEngine 方法默认加载 activiti.cfg.xml文件的配置信息 
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	/**
	 * 流程部署定义
	 */
//	@Test
	public void deploymentProcessDefinition() {
		//与流程部署和定义对象相关的service
		RepositoryService repositoryService = processEngine.getRepositoryService();
		//创建一个部署对象
		DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
		//添加部署名称
		deploymentBuilder.name("helloWorld入门程序");
		//从classpath加载资源文件，一次只能加载一个文件
		deploymentBuilder.addClasspathResource("diagrams/MyProcess.bpmn");
		deploymentBuilder.addClasspathResource("diagrams/MyProcess.png");
		//完成部署 返回流程对象
		Deployment deployment = deploymentBuilder.deploy();
		System.out.println("流程id： "+ deployment.getId()+" \n流程name： " +
				deployment.getName());
		
	}
	
	/**
	 * 启动流程引擎
	 */
//	@Test
	public void startProcessInstance() {
		//获取流程启动service
		RuntimeService runtimeService = this.processEngine.getRuntimeService();
		//使用流程定义的key （即bpmn文件对应的id）
		//(也是act_re_procdef表中对应的KEY_字段),默认是按照最新版本启动  
		String processDefinitionKey = "HelloWorld";
		//获取流程实例对象
		ProcessInstance processInstance = runtimeService.
				startProcessInstanceByKey(processDefinitionKey);
		System.out.println("流程实例ID："+processInstance.getId());//流程实例ID  
	    System.out.println("流程定义ID："+processInstance.getProcessDefinitionId());//流程定义ID
	}
	/**
	 * 查询当前个人任务（实际就是查询act_ru_task表）
	 */
//	@Test
	public void findMyPersonalTask() {
		String assignee = "王五";
		//获取任务service
		TaskService taskService = this.processEngine.getTaskService();
		List<Task> taskList = taskService.createTaskQuery() //创建查询对象
				.taskAssignee(assignee) //指定办理人
				.list(); //获取该办理人下的任务列表
		
		if(taskList!=null&&taskList.size()>0){  
	        for(Task task:taskList){  
	            System.out.println("任务ID："+task.getId());  
	            System.out.println("任务名称："+task.getName());  
	            System.out.println("任务的创建时间："+task.getCreateTime());  
	            System.out.println("任务办理人："+task.getAssignee());  
	            System.out.println("流程实例ID："+task.getProcessInstanceId());  
	            System.out.println("执行对象ID："+task.getExecutionId());  
	            System.out.println("流程定义ID："+task.getProcessDefinitionId());  
	            System.out.println("#############################################");  
	        }  
	    }  
	}
	/**
	 * 完成我的待办任务
	 */
//	@Test
	public void completeMyPersonalTask() {
		//查询代办任务时带出的任务Id
		String taskID = "15002";
		TaskService taskServie = this.processEngine.getTaskService();
		taskServie.complete(taskID);
		System.out.println("完成ID为"+taskID+"的任务");  
	}
	/**
	 * 部署流程定义（Zip）
	 * 
	 * activiti可以加载 将bpmn和png压缩的zip包
	 */
//	@Test
	public void deploymentProcessDefinitionZip() {
		//获取上传文件的输入流
		InputStream is = this.getClass().getClassLoader()
				.getResourceAsStream("diagrams/MyProcess.zip");
		//创建ZipInputStream对象
		ZipInputStream ZipIs = new ZipInputStream(is);
		RepositoryService repositoryService = this.processEngine.getRepositoryService();
		DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
		deploymentBuilder.name("helloWorld入门程序");
		deploymentBuilder.addZipInputStream(ZipIs);
		
		Deployment deployment = deploymentBuilder.deploy();
		//打印我们的流程信息  
	    System.out.println("部署Id:"+deployment.getId());  
	    System.out.println("部署名称Name:"+deployment.getName());
	}
	/*
	 * 查询流程定义信息
	 */
//	@Test
	public void queryProcessDefinition() {
		List<ProcessDefinition> pdList = this.processEngine.getRepositoryService()
				.createProcessDefinitionQuery()
//				.processDefinitionId("20001")
				.orderByProcessDefinitionVersion().asc()
				.list();
		//便利集合，查看内容  
	    for (ProcessDefinition pd:pdList) {  
	        System.out.println("id:"+pd.getId());  
	        System.out.println("name:"+pd.getName());  
	        System.out.println("key:"+pd.getKey());  
	        System.out.println("version:"+pd.getVersion());  
	        System.out.println("resourceName:"+pd.getDiagramResourceName());  
	        System.out.println("###########################################");  
	    }  
	    
	    List<Deployment> dlist = this.processEngine.getRepositoryService()
	    		.createDeploymentQuery()
	    		.list();
	    for(Deployment d : dlist) {
	    	System.out.println("id： "+d.getId());
	    }
	}
	/**
	 * 删除流程
	 */
//	@Test
	public void deleteDeployment() {
		String deploymentId = "20001";
		RepositoryService repositoryService = this.processEngine.getRepositoryService();
		repositoryService.deleteDeployment(deploymentId, true);
	}
	
	/**
	 * 查看流程图片
	 * @throws IOException 
	 */
//	@Test
	public void viewImage() throws IOException {
		String deploymentId = "1";
		List<String> names = this.processEngine.getRepositoryService()
				.getDeploymentResourceNames(deploymentId);
		String imageName = null;
		for(String name : names) {
			if(name.indexOf("png")!=-1) {
				imageName = name;
				break;
			}
		}
		System.out.println("imageName: " + imageName);
		if(imageName!=null) {
			File f = new File("d:/"+imageName);
			InputStream is = this.processEngine.getRepositoryService()
					.getResourceAsStream(deploymentId, imageName);
			copyFile(is, f);
		}
	}
	
	public void copyFile(InputStream is, File f) throws IOException {
		byte[] b = new byte[1024];
		int n=0;
		FileOutputStream out = new FileOutputStream(f);
		while((n = is.read(b))!=-1) {
			out.write(b, 0, n);
		}
	}
	/**
	 * 设置流程变量
	 */
//	@Test
	public void setVariables() {
		TaskService taskService = this.processEngine.getTaskService();
		List<Task> tList = taskService.createTaskQuery()
				.taskAssignee("李四")
				.list();
		User user = new User();
		user.setUserid("111");
		user.setUsername("王震");
		for (Task task : tList) {
			System.out.println("流程实例ID："+task.getProcessInstanceId());
			System.out.println("formkey: "+task.getFormKey());
			System.out.println("id: "+task.getId());
			System.out.println("name: "+task.getName());
			System.out.println("owner: "+task.getOwner());
			
//			taskService.setVariable(task.getId(), "审批人", "李四");
//			taskService.setVariable(task.getId(), "审批结果", "审批通过");
//			taskService.setVariable(task.getId(), "审批意见", "没事别老提申请");
			taskService.setVariable(task.getId(), "人员信息", user);
		}
	}
	/**
	 * 获取流程变量
	 */
//	@Test
	public void getVariables() {
		TaskService taskService = this.processEngine.getTaskService();
		List<Task> tList = taskService.createTaskQuery()
				.taskAssignee("李四")
				.list();
		for (Task task : tList) {
			String username = (String) taskService.getVariable(task.getId(), "审批人");
			String result = (String) taskService.getVariable(task.getId(), "审批结果");
			String suggest = (String) taskService.getVariable(task.getId(), "审批意见");
			System.err.println(username);
			System.err.println(result);
			System.err.println(suggest);
			User user = (User) taskService.getVariable(task.getId(), "人员信息");
			System.err.println(user.getUserid());
			System.err.println(user.getUsername());
		}
	}
	/**
	 * 查看流程定义走过多少实例
	 */
//	@Test
	public void queryHistoricProcessInstance() {
		HistoryService historyService = this.processEngine.getHistoryService();
		List<HistoricProcessInstance> historicProcessInstances = 
				historyService.createHistoricProcessInstanceQuery()
				.processDefinitionKey("HelloWorld")
				.list();
		for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
			System.err.println(historicProcessInstance.getId());
			System.err.println(historicProcessInstance.getProcessDefinitionId());
			System.err.println(historicProcessInstance.getProcessDefinitionKey());
			System.err.println(historicProcessInstance.getProcessDefinitionName());
		}
	}
	
	/**
	 * 查询工单历史活动？ 活动是包括开始 结束在内的所有节点
	 */
//	@Test
	public void queryHistoricActivityInstance() {
		String pid = "2501";
		HistoryService historyService = this.processEngine.getHistoryService();
		List<HistoricActivityInstance> historicActivityInstances = 
				historyService.createHistoricActivityInstanceQuery()
				.processInstanceId(pid)
				.list();
		for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
			System.err.println(historicActivityInstance.getActivityId());
			System.err.println(historicActivityInstance.getActivityName());
			System.err.println(historicActivityInstance.getActivityType());
			System.err.println(historicActivityInstance.getAssignee());
			System.err.println("#######################################");
		}
	}
	/**
	 * 查询某个工单所有历史任务节点，除了开始 结束 之外的环节
	 */
	@Test
	public void queryHistoricTask() {
		String pid = "2501";
		HistoryService historyService = this.processEngine.getHistoryService();
		List<HistoricTaskInstance> historicTaskInstances =
				historyService.createHistoricTaskInstanceQuery()
				.processInstanceId(pid)
				.list();
		for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
			System.err.println(historicTaskInstance.getId());
			System.err.println(historicTaskInstance.getName());
			System.err.println(historicTaskInstance.getOwner());
			System.err.println(historicTaskInstance.getTaskDefinitionKey());
			System.err.println("############################");
		}
	}
}
